package net.itren.jetpackdemo.utils.network

import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.IOException
import java.util.*
import java.util.concurrent.TimeUnit

object NetworkUtils {
    val MEDIA_TYPE_MARKDOWN = "text/x-markdown; charset=utf-8".toMediaType()
    val JSON_TYPE_MARKDOWN = "application/json; charset=utf-8".toMediaType();

    //创建请求客户端, 同时设置各项过期时间
    private val client = OkHttpClient.Builder()
        .connectTimeout(5, TimeUnit.SECONDS)
        .writeTimeout(5, TimeUnit.SECONDS)
        .readTimeout(5, TimeUnit.SECONDS)
        .callTimeout(10, TimeUnit.SECONDS)
        .build()

    fun synchronousGet(
        url: String,
        params: Map<String, Any>,
        header: Map<String, String?>? = null
    ) {
        val request = Request.Builder()
            .url(getUrl(url, params))
        setHeader(request, header)
        synExecute(request.build())
    }

    fun asynchronousGet(
        url: String,
        params: Map<String, Any>,
        header: Map<String, String?>? = null
    ) {
        val request = Request.Builder()
            .url(getUrl(url, params))
        setHeader(request, header)
        synExecute(request.build())
    }

    fun synchronousPost(url: String, postJsonParam: String, header: Map<String, String?>? = null) {
        val builder =
            Request.Builder().url(url).post(postJsonParam.toRequestBody(JSON_TYPE_MARKDOWN))
        setHeader(builder, header)
        synExecute(builder.build())
    }

    fun asynchronousPost(url: String, postJsonParam: String, header: Map<String, String?>) {
        val builder =
            Request.Builder().url(url).post(postJsonParam.toRequestBody(JSON_TYPE_MARKDOWN))
        asynExecute(builder.build())
    }

    fun doUploadFile(
        url: String,
        params: HttpParams,
        header: Map<String, String?>?
    ) {
        val multipartBodyBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)
        if (params != null) {
            val param = params.urlParamsMap;
            if (param != null) {
                for (item in param) {
                    multipartBodyBuilder.addFormDataPart(item.key, item.value)

                }
            }
            var fileMap = params.fileParamsMap;
            if (fileMap != null) {
                for (item in fileMap) {
                    val fileWrapper = item.value;
                    multipartBodyBuilder.addFormDataPart(
                        item.key, fileWrapper.fileName, fileWrapper.file.asRequestBody()
                    )
                }
            }
        }

        val builder: Request.Builder = Request.Builder()
            .url(url)
            .post(multipartBodyBuilder.build())
        setHeader(builder, header)
        asynExecute(builder.build());
    }


    //设置请求头
    private fun setHeader(
        builder: Request.Builder,
        header: Map<String, String?>? = null
    ): Request.Builder {
        if (header != null && header!!.isNotEmpty()) {
            for (param in header) {
                builder.addHeader(param.key, param.value.toString())
            }
        }


        return builder
    }


    //同步: 请求最终的执行方法,
    private fun synExecute(request: Request) {
        client.newCall(request).execute().use { response ->
            if (!response.isSuccessful) throw IOException("Unexpected code $response")
            for ((name, value) in response.headers) {
                println("$name: $value")
            }

            println(response.body!!.string())
        }
    }

    //异步: 请求最终的执行方法,
    private fun asynExecute(request: Request) {
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
            }

            override fun onResponse(call: Call, response: Response) {
                response.use {
                    if (!it.isSuccessful) throw IOException("Unexpected code $response")

                    for ((name, value) in it.headers) {
                        println("$name: $value")
                    }
                    println(it.body!!.string())
                }
            }
        })
    }

    //拼接get请求参数
    private fun getUrl(url: String, params: Map<String, Any>): String {
        val builder = url.toHttpUrlOrNull()?.newBuilder()
        if (params.isNotEmpty()) {
            for (param in params) {
                builder?.addQueryParameter(param.key, param.value.toString())
            }
        }
        return builder?.build().toString();
    }


}

fun main() {
//    val arr = mutableMapOf<String, Any>()
//    arr["word"] = 52
//    NetworkUtils.asynchronousGet("http://127.0.0.1:8965/app/bus/search", arr)

//    var fileList = mutableListOf<File>()
    val element = File("/Users/liangjun/Desktop/temp/abc.png")
    val param = HttpParams()


    var fileWrapper = FileWrapper(element, "新的流程图.png", null);

    param.put("file",fileWrapper)
    param.put("fileName","流程图.png")
    param.put("fileSuffix","png")

    NetworkUtils.doUploadFile("http://127.0.0.1:8965/util/upload/file", param, null)

}